package csrpg;

import java.io.*;
import java.net.*;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import org.twgg.cssula.ConsoleTool;

public class Server {
    private ServerSocket srvSock;
    private Socket clnSock;
    private Hashtable<Character, ChildServer> users = new Hashtable<Character, ChildServer>();
    private final int port = 1123;
    private static Object lock = new Object();
    private Map map = new Map("map/map");

    public Server(){
        try{
            srvSock = new ServerSocket(port);
            System.out.println("Server started at "+ new Date() + " with port "+port);
            while(true){
                clnSock = srvSock.accept();
                System.out.println("connected with "+clnSock.getInetAddress().getHostAddress());
                new ChildServer(clnSock).start();
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args){
        new Server();
    }
    
    class ChildServer extends Thread{
        private Socket clnSock;
        private DataInputStream sockIn;
        private DataOutputStream sockOut;
        public ChildServer(Socket clnSock){
            this.clnSock = clnSock;
            try{
                sockIn = new DataInputStream(new BufferedInputStream(clnSock.getInputStream()));
                sockOut = new DataOutputStream(new BufferedOutputStream(clnSock.getOutputStream()));
            }catch(Exception e){
                e.printStackTrace();
            }
            
        }
        
        @Override
        public void run(){
            try{
                ChildServer cs;
                char name;
                for(;;){
                    name = sockIn.readChar();
                    if(!users.containsKey(name)) break;
                    sockOut.writeBoolean(false);
                    sockOut.flush();
                }
                System.out.println("Player "+name+" has been in.");
                sockOut.writeBoolean(true);
                sockOut.flush();
                users.put(name, this);
                map.add(new Role(map, name, ConsoleTool.INDIGO|ConsoleTool.BRIGHT, 100), 2, 2);

                while(true){
                    int x = sockIn.readInt();
                    int y = sockIn.readInt();
                    for (Iterator<Character> i = users.keySet().iterator(); i.hasNext();) {
                        cs = users.get(i.next());
                        if (cs != this) {
                            synchronized(lock){
                                cs.sockOut.writeChar(name);
                                cs.sockOut.writeInt(x);
                                cs.sockOut.writeInt(y);
                                cs.sockOut.flush();
                            }
                        }
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}